package nancal.mp.mvc.devops

import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import nancal.mp.db.mongo.entity.dev.*
import nancal.mp.db.mongo.mor
import nbcp.base.annotation.*
import nbcp.base.annotation.mvc.*
import nbcp.base.comm.*
import nbcp.base.db.IdCodeName
import nbcp.base.extend.*
import nbcp.base.json.*
import nbcp.mvc.sys.*
import nbcp.myoql.db.mongo.*

import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.servlet.http.HttpServletRequest

/**
 * Created by CodeGenerator at 2021-04-09 15:38:25
 */
@Api(description = "产品线", tags = arrayOf("ProductLine"))
@RestController
@RequestMapping("/dev/product-line")
class ProductLineAutoController {

    public class ProductLineWithGitCount : ProductLine() {
        var gitCount: Int = 0
    }

    @ApiOperation("列表")
    @PostMapping("/list")
    fun list(
        id: String, //当列表列新一条后，刷新时使用
        name: String,
        clusterCode: String,
        clusterIndex: String,
        user: String,
        @DefaultSort("cluster.index",true) @org.springframework.web.bind.annotation.RequestBody query: PagerModel<Any?>,
        request: HttpServletRequest
    ): ListResult<ProductLineWithGitCount> {

        var ret = mor.dev.productLine.query()
            .apply {
                if (id.HasValue) {
                    this.where { it.id mongoEquals id }
                }
                if (name.HasValue) {
                    this.linkOr({ it.name mongoLike name }, { it.code mongoLike name })
                }
                if (clusterCode.HasValue) {
                    this.where { it.cluster.code mongoEquals clusterCode }
                }
                if (clusterIndex.HasValue) {
                    this.where { it.cluster.index mongoEquals clusterIndex }
                }

                if (user.HasValue) {
                    this.linkOr(
                        { it.leader.name mongoLike user },
                        { it.lm.name mongoLike user },
                        { it.pm.name mongoLike user },
                        { it.developers.name mongoLike user }
                    )
                }
            }
            .withPager(query)
            .toListResult(ProductLineWithGitCount::class.java)

        var gitCountMap = mor.dev.gitData.aggregate()
            .beginMatch()
            .where{it.productLine.id mongoIn ret.data.map{it.id}}
            .endMatch()
            .groupWithId(
                "\$productLine.code",
                JsonMap(
                    "total" to JsonMap("\$sum" to 1)
                )
            )
            .toMapList();

        ret.data.forEach { row ->
            row.gitCount = gitCountMap.firstOrNull { it.get("id") == row.code }?.get("total").AsInt()
        }
        return ret;
    }

    @ApiOperation("详情")
    @PostMapping("/detail/{id}")
    fun detail(
        @Require id: String,
        request: HttpServletRequest
    ): ApiResult<ProductLine> {
        mor.dev.productLine.queryById(id)
            .toEntity()
            .apply {
                if (this == null) {
                    return ApiResult.error<ProductLine>("找不到数据")
                }

                return ApiResult.of(this)
            }
    }

    @ApiOperation("更新")
    @PostMapping("/save")
    fun save(
        @org.springframework.web.bind.annotation.RequestBody entity: ProductLine,
        request: HttpServletRequest
    ): ApiResult<String> {
        //鉴权
        var userId = request.UserId;

        val isUpdate = entity.id.HasValue;
        var oriProductLine: ProductLine? = null;
        if (isUpdate) {
            oriProductLine = mor.dev.productLine.queryById(entity.id).toEntity();
        }

        mor.dev.productLine.updateWithEntity(entity)
            .run {
                if (isUpdate) {
                    return@run this.execUpdate()
                } else {
                    return@run this.execInsert()
                }
            }
            .apply {
                if (this == 0) {
                    return ApiResult.error("更新失败")
                }
            }


        //更新gitData
        if (isUpdate) {
            mor.dev.gitData.update()
                .where { it.productLine.id mongoEquals oriProductLine!!.id }
                .set { it.productLine to IdCodeName(entity.id, entity.code, entity.name) }
                .set { it.clusterCode to entity.clusterCode }
                .exec()
        }


        return ApiResult.of(entity.id)
    }

    @ApiOperation("删除")
    @PostMapping("/chk-data")
    fun chkData(): JsonResult {
        var productLines = mor.dev.productLine.query().toList();

        var emptyClusters = productLines.filter { it.cluster.code.isEmpty() }.map { it.name }.joinToString(",")
        if (emptyClusters.HasValue) {
            return JsonResult.error("${emptyClusters} 是空集群!")
        }


        var emptyProductLineGitData = mor.dev.gitData.query()
            .where { it.productLine.code.mongoIsNullOrEmpty() }
            .toEntity();
        if (emptyProductLineGitData != null) {
            return JsonResult.error("${emptyProductLineGitData.name} 没有产品线!")
        }

        return JsonResult();
    }


    @ApiOperation("删除")
    @PostMapping("/delete/{id}")
    fun delete(
        @Require id: String,
        withRowData: Boolean = false,
        request: HttpServletRequest
    ): JsonResult {
        //鉴权
        var userId = request.UserId

//        var entity = mor.dev.productLine.queryById(id).toEntity()
//        if (entity == null) {
//            return JsonResult.error("找不到数据")
//        }

        if (withRowData) {
            mor.dev.gitData.delete()
                .where { it.productLine.id mongoEquals id }
                .exec()
        }

        mor.dev.productLine.deleteById(id)
            .exec()
            .apply {
                if (this == 0) {
                    return JsonResult.error("删除失败")
                }
                //实体上配置垃圾箱功能，可物理删除，会自动移到垃圾箱。
                return JsonResult()
            }
    }
}
